#include "Tank.h"
#include <string.h>
#include <cstdlib>
#include <cmath>
#include <fstream>
#include <list>
#include <vector>
using namespace std;
//请勿修改以上头文件
/*

 您可以在这里添加您所需头文件

 */
#include "core.h"
#include "utils.h"

struct __TankRecord {
	int index;
	int distance;
};

OrderType getDirectionFromTo(int from_row, int from_col, int to_row, int to_col) {
	if (from_row < to_row) {
		return GODOWN;
	} else if (from_row > to_row) {
		return GOUP;
	} else if (from_col < to_col) {
		return GORIGHT;
	} else {
		return GOLEFT;
	}
}

vector<__TankRecord>collectDangerousTanksToPoint (int row, int col) {
	vector<__TankRecord> enemies;
	for(int i = 0; i < MAX_TANK_NUM; i++)
	{
		if(gdata.tank[i].flag != gdata.myFlag) {
			if(gdata.tank[i].row != -2) {
				int distance = abs(gdata.tank[i].row - row) + abs(gdata.tank[i].col - col);
				if(gdata.tank[i].range >= distance) {
					__TankRecord record;
					record.index = i;
					record.distance = distance;
					enemies.push_back(record);
				}
			}
		}
	}
	return enemies;
}

vector<__TankRecord>collectAttackableTanksAtPoint (int row, int col, int range) {
	vector<__TankRecord> enemies;
	for(int i = 0; i < MAX_TANK_NUM; i++)
	{
		if(gdata.tank[i].flag != gdata.myFlag) {
			if(gdata.tank[i].row != -2) {
				int distance = abs(gdata.tank[i].row - row) + abs(gdata.tank[i].col - col);
				if(range >= distance) {
					__TankRecord record;
					record.index = i;
					record.distance = distance;
					enemies.push_back(record);
				}
			}
		}
	}
	return enemies;
}

int getTotalAttackOfEnemies(vector<__TankRecord>enemies ) {
	int totalAttack = 0;
	for(int i = 1; i < enemies.size(); i ++) {
		totalAttack += gdata.tank[enemies[i].index].attack;
	}
	return totalAttack;
}

struct __Dangerous {
	int round;
	bool dangerous;
};

__Dangerous gDangerousMap[MAP_HEIGHT][MAP_WIDTH];

bool willDieAtPoint(int row, int col, int life) {
	if (gdata.round == 0) {
		__Dangerous d;
		d.round = -1;
		d.dangerous = false;
		for (int i = 1; i < MAP_HEIGHT; i++) {
			for (int j = 1; j < MAP_HEIGHT; j++) {
				gDangerousMap[i][j] = d;
			}
		}
	}

	if (gdata.round == gDangerousMap[row][col].round) {
		return gDangerousMap[row][col].dangerous;
	}

	vector<__TankRecord>enemies = collectDangerousTanksToPoint(row, col);

	if(enemies.size() == 0) {
		return false;
	}

	int totalAttack = getTotalAttackOfEnemies(enemies);
	bool dangerous = (totalAttack >= life);
	gDangerousMap[row][col].dangerous = dangerous;
	gDangerousMap[row][col].round = gdata.round;
	return dangerous;
}

list<Choice> makeChoiceByBeaten(DataForAI& data) {
	list<Choice> ls;

	TankData& me = data.tank[data.myID];

	vector<__TankRecord>enemies = collectDangerousTanksToPoint(me.row, me.col);

	if(enemies.size() == 0) {
		return ls;
	}

	int totalAttack = getTotalAttackOfEnemies(enemies);

	vector<__TankRecord> attackables = collectAttackableTanksAtPoint(me.row, me.col, me.range);

	if(attackables.size() == 0) {
		//这种情况也不可能有邻居
		if(totalAttack >= me.life) {
			//死定了
			return ls;
		} else {
			//没敌人tank做目标，没有选择。 该点
			if(enemies.size()==1) {
				if(me.type==Pioneer) {
					if(destination[me.ID]) {
						//fout<<"Herer"<<endl;
						short sourceNum = destination[me.ID]-1;
						Point mePoint;
						mePoint.row = me.row;
						mePoint.col = me.col;
						PathFindingResult pathFindingResult = pathFindingUsingAStar2(mePoint,gdata.source[sourceNum]);
						if(pathFindingResult.takeSourceStep>=4) {
                           __TankRecord tankRecord = enemies[0];
                           short number = tankRecord.index;
                           Point endPoint;
                           endPoint.row = data.tank[number].row;
                           endPoint.col = data.tank[number].col;
                           PathFindingResult pathFindingResultTo = pathFindingUsingAStar2(mePoint,endPoint);
                           Choice choice;
                           choice.order = getOrder(mePoint.row,mePoint.col,pathFindingResultTo.nextPoint.row,pathFindingResultTo.nextPoint.col,gdata);
                           choice.takeSourceStep = pathFindingResultTo.takeSourceStep;
                           ls.push_back(choice);
						}
					}
				}
			}
			return ls;
		}
	} else {
		int minLifeIndex = 0;
		for(int i = 1; i < attackables.size(); i ++) {
			if(gdata.tank[attackables[i].index].life < gdata.tank[attackables[minLifeIndex].index].life) {
				minLifeIndex = i;
			}
		}

		TankData& target = gdata.tank[attackables[minLifeIndex].index];
		Choice c;
		c.order.type = FIRE;
		c.order.col = target.col;
		c.order.row = target.row;
		c.takeSourceStep = 1000;
		c.willDie = (totalAttack >= me.life);
		c.willKill = (target.life <= me.attack);
		ls.push_back(c);
		return ls;
	}

}

